package kgame5.k3d.core.render.layerrender.impl.zbuffer {
import kgame5.k3d.core.obj3d.info.geometry.Face3D;
import kgame5.k3d.core.obj3d.info.geometry.GeometryInfo;
import kgame5.k3d.core.obj3d.info.material.MaterialInfo;
import kgame5.k3d.core.obj3d.info.transform.TransformInfo;
import kgame5.k3d.core.render.RenderSessionData;
import kgame5.k3d.core.render.layerrender.LayerRender;

import flash.display.BitmapData;
import flash.display.Shape;

/**
 * @author kangkai
 * 以zbuffer的方式来渲染
 * 注意这个我使用了一个偏移，NXFace3DWraper和ZBufferLayerRender用了偏移，保证对其
 */
public class ZBufferLayerRender extends LayerRender{
	
	public var bSmothing:Boolean=true;
	//画布的大小
	private var viewWidth:int;
	private var viewHeight:int;
	private var cam:ClipCamera3D;
	private var _zbuffer:ZBuffer;
	private var bmd:BitmapData;
	private var W2:int,H2:int;
	
	public function ZBufferLayerRender(viewWidth:int,viewHeight:int){
		mc=new Shape();
		g=(mc as Shape).graphics;
		
		this.viewWidth=viewWidth;
		this.viewHeight=viewHeight;
		cam=new ClipCamera3D();
		cam.max_clip_x=viewWidth-1;
		cam.max_clip_y=viewHeight-1;
		
		_zbuffer=new ZBuffer(viewWidth,viewHeight);
		
		W2=viewWidth/2;
		H2=viewHeight/2;
		
		mc.x=-W2;
		mc.y=-H2;
	}

	//整个渲染BestGroup3D
	override public function  render(gi:GeometryInfo,mi:MaterialInfo,ti:TransformInfo,session:RenderSessionData):void{
		
		//面排序
		doSort(aOuterFace);
		
		//绘制,为每个三角面传送一次贴图
		doBestDraw(aOuterFace,session);
	}
	
	//真正画到屏幕上,为每个三角面单独传送贴图
	private function doBestDraw(aSortedFace:Array,session:RenderSessionData):void{
		
			
			
			//this.bmd.dispose();
			//TODO 这个可以快速的解决bmd的问题
			//bmd.floodFill(x, y, color)
			
			//画到bmd上
			this.bmd=new BitmapData(_zbuffer.width,_zbuffer.height,true,0x000000);
			this.bmd.lock();
			
			this._zbuffer.clear();
			for each(var face:Face3D in aSortedFace){
//				if(face.mi==null||face.mi.bmd==null){
//					trace("有空的");
//					return;
//				}
				var ff:NXFace3DWraper=new NXFace3DWraper(face,W2,H2);
				
				draw(ff,face.mi.bmd);
			}
			
		    this.bmd.unlock();
		    
		    //真正画到屏幕上
			g.clear();
			g.beginBitmapFill(this.bmd,null,true,bSmothing);
			g.drawRect(0, 0, _zbuffer.width, _zbuffer.height);
			g.endFill();
	}
	//var kkkk:int=0;
	private function draw(face:NXFace3DWraper,textmap:BitmapData):void
		{
//			if(kkkk==0){
//				//kkkk=1;
//				trace("ddd");
//				trace(face.tvlist[0]);
//				trace(face.tvlist[1]);
//				trace(face.tvlist[2]);
//				
//				trace(face.tlist[0]);
//				trace(face.tlist[1]);
//				trace(face.tlist[2]);
//			}
			var v0:int=0,
			    v1:int=1,
				v2:int=2,
				tri_type:int = ConstClass.TRI_TYPE_NONE,
				irestart:int = ConstClass.INTERP_LHS;
			
			var dx:int,dy:int,dyl:int,dyr:int,      
			    
			    du:int,dv:int,dz:int,
			    xi:int,yi:int,              
				ui:int,vi:int,zi:int,         
				
			        
				xstart:int,
				xend:int,
				ystart:int,
				yrestart:int,
				yend:int,
				xl:int,                 
				dxdyl:int,              
				xr:int,
				dxdyr:int,             
				dudyl:int,    
				ul:int,
				dvdyl:int,   
				vl:int,
				dzdyl:int,   
				zl:int,
				dudyr:int,
				ur:int,
				dvdyr:int,
				vr:int,
				dzdyr:int,
				zr:int;
			
			var x0:int,y0:int,tu0:Number,tv0:Number,tz0:int,  
				x1:int,y1:int,tu1:Number,tv1:Number,tz1:int,
				x2:int,y2:int,tu2:Number,tv2:Number,tz2:int;
				
			var  z_ptr:Array=_zbuffer.data;
			
		
			
			//var texture_shift2:int = face.mi.textureShift2;
			
			face.tvlist[0].x = (int)(face.tvlist[0].x+0.5);
			face.tvlist[0].y = (int)(face.tvlist[0].y+0.5);
			
			face.tvlist[1].x = (int)(face.tvlist[1].x+0.5);
			face.tvlist[1].y = (int)(face.tvlist[1].y+0.5);
			
			face.tvlist[2].x = (int)(face.tvlist[2].x+0.5);
			face.tvlist[2].y = (int)(face.tvlist[2].y+0.5);
			
			if (((face.tvlist[0].y < cam.min_clip_y)  && 
				 (face.tvlist[1].y < cam.min_clip_y)  &&
				 (face.tvlist[2].y < cam.min_clip_y)) ||
			
				((face.tvlist[0].y > cam.max_clip_y)  && 
				 (face.tvlist[1].y > cam.max_clip_y)  &&
				 (face.tvlist[2].y > cam.max_clip_y)) ||
			
				((face.tvlist[0].x < cam.min_clip_x)  && 
				 (face.tvlist[1].x < cam.min_clip_x)  &&
				 (face.tvlist[2].x < cam.min_clip_x)) ||
			
				((face.tvlist[0].x > cam.max_clip_x)  && 
				 (face.tvlist[1].x > cam.max_clip_x)  &&
				 (face.tvlist[2].x > cam.max_clip_x)))
			   return;
			
			if (face.tvlist[v1].y < face.tvlist[v0].y) 
				{v0=v1+(v1=v0)*0;} 
			
			if (face.tvlist[v2].y < face.tvlist[v0].y) 
				{v0=v2+(v2=v0)*0;}
			
			if (face.tvlist[v2].y < face.tvlist[v1].y) 
				{v1=v2+(v2=v1)*0;}
			
			if (FCMP(face.tvlist[v0].y, face.tvlist[v1].y) )
				{ 
				tri_type = ConstClass.TRI_TYPE_FLAT_TOP;
			
				if (face.tvlist[v1].x < face.tvlist[v0].x) 
					{v0=v1+(v1=v0)*0;}
			
				} 
			else
			if (FCMP(face.tvlist[v1].y ,face.tvlist[v2].y))
				{ 
				tri_type = ConstClass.TRI_TYPE_FLAT_BOTTOM;
			
				if (face.tvlist[v2].x < face.tvlist[v1].x) 
					{v1=v2+(v2=v1)*0;}
				
				} 
			else
				{
				tri_type = ConstClass.TRI_TYPE_GENERAL;
			
				} 
			
			x0  = (int)(face.tvlist[v0].x);
			y0  = (int)(face.tvlist[v0].y);
			tu0 = (face.tlist[v0].x);
			tv0 = (face.tlist[v0].y);
			tz0 = (int)(face.tvlist[v0].z+0.5);
			
			x1  = (int)(face.tvlist[v1].x);
			y1  = (int)(face.tvlist[v1].y);
			tu1 = (face.tlist[v1].x);
			tv1 = (face.tlist[v1].y);
			tz1 = (int)(face.tvlist[v1].z+0.5);
			
			x2  = (int)(face.tvlist[v2].x);
			y2  = (int)(face.tvlist[v2].y);
			tu2 = (face.tlist[v2].x);
			tv2 = (face.tlist[v2].y);
			tz2 = (int)(face.tvlist[v2].z+0.5);
			if ( ((x0 == x1) && (x1 == x2)) || ((y0 ==  y1) && (y1 == y2)))
			   return;
			
			yrestart = y1;
			
			if (tri_type & ConstClass.TRI_TYPE_FLAT_MASK)
			{
			
				if (tri_type == ConstClass.TRI_TYPE_FLAT_TOP)
				{
					dy = (y2 - y0);
				
					dxdyl = ((x2 - x0)   << ConstClass.FIXP16_SHIFT)/dy;
					dudyl = ((tu2 - tu0) << ConstClass.FIXP16_SHIFT)/dy;  
					dvdyl = ((tv2 - tv0) << ConstClass.FIXP16_SHIFT)/dy;    
					dzdyl = ((tz2 - tz0) << ConstClass.FIXP16_SHIFT)/dy;    
				
					dxdyr = ((x2 - x1)   << ConstClass.FIXP16_SHIFT)/dy;
					dudyr = ((tu2 - tu1) << ConstClass.FIXP16_SHIFT)/dy;  
					dvdyr = ((tv2 - tv1) << ConstClass.FIXP16_SHIFT)/dy;   
					dzdyr = ((tz2 - tz1) << ConstClass.FIXP16_SHIFT)/dy;  
				
					if (y0 < cam.min_clip_y)
					{
						dy = (cam.min_clip_y - y0);
				
						xl = dxdyl*dy + (x0  << ConstClass.FIXP16_SHIFT);
						ul = dudyl*dy + (tu0 << ConstClass.FIXP16_SHIFT);
						vl = dvdyl*dy + (tv0 << ConstClass.FIXP16_SHIFT);
						zl = dzdyl*dy + (tz0 << ConstClass.FIXP16_SHIFT);
				
						xr = dxdyr*dy + (x1  << ConstClass.FIXP16_SHIFT);
						ur = dudyr*dy + (tu1 << ConstClass.FIXP16_SHIFT);
						vr = dvdyr*dy + (tv1 << ConstClass.FIXP16_SHIFT);
						zr = dzdyr*dy + (tz1 << ConstClass.FIXP16_SHIFT);
				
						ystart = cam.min_clip_y;
			
					} 
					else
					{
						xl = (x0 << ConstClass.FIXP16_SHIFT);
						xr = (x1 << ConstClass.FIXP16_SHIFT);
				
						ul = (tu0 << ConstClass.FIXP16_SHIFT);
						vl = (tv0 << ConstClass.FIXP16_SHIFT);
						zl = (tz0 << ConstClass.FIXP16_SHIFT);
				
						ur = (tu1 << ConstClass.FIXP16_SHIFT);
						vr = (tv1 << ConstClass.FIXP16_SHIFT);
						zr = (tz1 << ConstClass.FIXP16_SHIFT);
				
						ystart = y0;
			
					} 
			
				} 
				else
				{
					dy = (y1 - y0);
				
					dxdyl = ((x1 - x0)   << ConstClass.FIXP16_SHIFT)/dy;
					dudyl = ((tu1 - tu0) << ConstClass.FIXP16_SHIFT)/dy;  
					dvdyl = ((tv1 - tv0) << ConstClass.FIXP16_SHIFT)/dy;    
					dzdyl = ((tz1 - tz0) << ConstClass.FIXP16_SHIFT)/dy;   
				
					dxdyr = ((x2 - x0)   << ConstClass.FIXP16_SHIFT)/dy;
					dudyr = ((tu2 - tu0) << ConstClass.FIXP16_SHIFT)/dy;  
					dvdyr = ((tv2 - tv0) << ConstClass.FIXP16_SHIFT)/dy;   
					dzdyr = ((tz2 - tz0) << ConstClass.FIXP16_SHIFT)/dy;   
			
					if (y0 < cam.min_clip_y)
					{
						dy = (cam.min_clip_y - y0);
				
						xl = dxdyl*dy + (x0  << ConstClass.FIXP16_SHIFT);
						ul = dudyl*dy + (tu0 << ConstClass.FIXP16_SHIFT);
						vl = dvdyl*dy + (tv0 << ConstClass.FIXP16_SHIFT);
						zl = dzdyl*dy + (tz0 << ConstClass.FIXP16_SHIFT);
				
						xr = dxdyr*dy + (x0  << ConstClass.FIXP16_SHIFT);
						ur = dudyr*dy + (tu0 << ConstClass.FIXP16_SHIFT);
						vr = dvdyr*dy + (tv0 << ConstClass.FIXP16_SHIFT);
						zr = dzdyr*dy + (tz0 << ConstClass.FIXP16_SHIFT);
				
						ystart = cam.min_clip_y;
			
					} 
					else
					{
					
						xl = (x0 << ConstClass.FIXP16_SHIFT);
						xr = (x0 << ConstClass.FIXP16_SHIFT);
				
						ul = (tu0 << ConstClass.FIXP16_SHIFT);
						vl = (tv0 << ConstClass.FIXP16_SHIFT);
						zl = (tz0 << ConstClass.FIXP16_SHIFT);
				
						ur = (tu0 << ConstClass.FIXP16_SHIFT);
						vr = (tv0 << ConstClass.FIXP16_SHIFT);
						zr = (tz0 << ConstClass.FIXP16_SHIFT);
				
						ystart = y0;
			
					} 
			
				} 
			
				if ((yend = y2) > cam.max_clip_y)
					yend = cam.max_clip_y;
			
				if ((x0 < cam.min_clip_x) || (x0 > cam.max_clip_x) ||
					(x1 < cam.min_clip_x) || (x1 > cam.max_clip_x) ||
					(x2 < cam.min_clip_x) || (x2 > cam.max_clip_x))
				{
			
					for (yi = ystart; yi<=yend; yi++)
					{
						xstart = ((xl + ConstClass.FIXP16_ROUND_UP) >> ConstClass.FIXP16_SHIFT);
						xend   = ((xr + ConstClass.FIXP16_ROUND_UP) >> ConstClass.FIXP16_SHIFT);
				
						ui = ul + ConstClass.FIXP16_ROUND_UP;
						vi = vl + ConstClass.FIXP16_ROUND_UP;
						zi = zl + ConstClass.FIXP16_ROUND_UP;
					
						if ((dx = (xend - xstart))>0)
						{
							du = (ur - ul)/dx;
							dv = (vr - vl)/dx;
							dz = (zr - zl)/dx;
						} 
						else
						{
							du = (ur - ul);
							dv = (vr - vl);
							dz = (zr - zl);
						} 
			
			
						if (xstart < cam.min_clip_x)
						{
							dx = cam.min_clip_x - xstart;
				
							ui+=dx*du;
							vi+=dx*dv;
							zi+=dx*dz;
							
							xstart = cam.min_clip_x;
			
						} 
					
						if (xend > cam.max_clip_x)
							xend = cam.max_clip_x;
			
			
						for (xi=xstart; xi<=xend; xi++)
						{
				            if (zi < z_ptr[yi][xi]||z_ptr[yi][xi]==null)
							{
				               bmd.setPixel32(xi,yi,textmap.getPixel32((ui >> ConstClass.FIXP16_SHIFT) , ((vi >> ConstClass.FIXP16_SHIFT) )));
				               z_ptr[yi][xi] = zi;           
				            } 
							
							ui+=du;
							vi+=dv;
							zi+=dz;
						} 
			
						xl+=dxdyl;
						ul+=dudyl;
						vl+=dvdyl;
						zl+=dzdyl;
					
						xr+=dxdyr;
						ur+=dudyr;
						vr+=dvdyr;
						zr+=dzdyr;
			 
					} 
			
				} 
				else
				{
			
					for (yi = ystart; yi<=yend; yi++)
					{
						xstart = ((xl + ConstClass.FIXP16_ROUND_UP) >> ConstClass.FIXP16_SHIFT);
						xend   = ((xr + ConstClass.FIXP16_ROUND_UP) >> ConstClass.FIXP16_SHIFT);
					
						ui = ul + ConstClass.FIXP16_ROUND_UP;
						vi = vl + ConstClass.FIXP16_ROUND_UP;
						zi = zl + ConstClass.FIXP16_ROUND_UP;
				
						if ((dx = (xend - xstart))>0)
						{
							du = (ur - ul)/dx;
							dv = (vr - vl)/dx;
							dz = (zr - zl)/dx;
						} 
						else
						{
							du = (ur - ul);
							dv = (vr - vl);
							dz = (zr - zl);
						} 
			
						for (xi=xstart; xi<=xend; xi++)
						{
				            if (zi < z_ptr[yi][xi]||z_ptr[yi][xi]==null)
				            {
				               bmd.setPixel32(xi,yi,textmap.getPixel32((ui >> ConstClass.FIXP16_SHIFT) , ((vi >> ConstClass.FIXP16_SHIFT) )));
				
				               z_ptr[yi][xi] = zi;            
				               }
							
							ui+=du;
							vi+=dv;
							zi+=dz;
						} 
			
						xl+=dxdyl;
						ul+=dudyl;
						vl+=dvdyl;
						zl+=dzdyl;
					
						xr+=dxdyr;
						ur+=dudyr;
						vr+=dvdyr;
						zr+=dzdyr;
			
					
			
					} 
			
				} 
			
			} 
			else
			if (tri_type==ConstClass.TRI_TYPE_GENERAL)
			{
				if ((yend = y2) > cam.max_clip_y)
					yend = cam.max_clip_y;
			
				if (y1 < cam.min_clip_y)
				{
					dyl = (y2 - y1);
			
					dxdyl = ((x2  - x1)  << ConstClass.FIXP16_SHIFT)/dyl;
					dudyl = ((tu2 - tu1) << ConstClass.FIXP16_SHIFT)/dyl;  
					dvdyl = ((tv2 - tv1) << ConstClass.FIXP16_SHIFT)/dyl;    
					dzdyl = ((tz2 - tz1) << ConstClass.FIXP16_SHIFT)/dyl;  
					
					dyr = (y2 - y0);	
			
					dxdyr = ((x2  - x0)  << ConstClass.FIXP16_SHIFT)/dyr;
					dudyr = ((tu2 - tu0) << ConstClass.FIXP16_SHIFT)/dyr;  
					dvdyr = ((tv2 - tv0) << ConstClass.FIXP16_SHIFT)/dyr;   
					dzdyr = ((tz2 - tz0) << ConstClass.FIXP16_SHIFT)/dyr;   
					
					dyr = (cam.min_clip_y - y0);
					dyl = (cam.min_clip_y - y1);
			
					xl = dxdyl*dyl + (x1  << ConstClass.FIXP16_SHIFT);
					ul = dudyl*dyl + (tu1 << ConstClass.FIXP16_SHIFT);
					vl = dvdyl*dyl + (tv1 << ConstClass.FIXP16_SHIFT);
					zl = dzdyl*dyl + (tz1 << ConstClass.FIXP16_SHIFT);
			
					xr = dxdyr*dyr + (x0  << ConstClass.FIXP16_SHIFT);
					ur = dudyr*dyr + (tu0 << ConstClass.FIXP16_SHIFT);
					vr = dvdyr*dyr + (tv0 << ConstClass.FIXP16_SHIFT);
					zr = dzdyr*dyr + (tz0 << ConstClass.FIXP16_SHIFT);
			
					ystart = cam.min_clip_y;
			
					if (dxdyr > dxdyl)
					{
						dxdyl=dxdyr+(dxdyr=dxdyl)*0;
						dudyl=dudyr+(dudyr=dudyl)*0;	
						dvdyl=dvdyr+(dvdyr=dvdyl)*0;
						dzdyl=dzdyr+(dzdyr=dzdyl)*0;
						xl=xr+(xr=xl)*0;
						ul=ur+(ur=ul)*0;
						vl=vr+(vr=vl)*0;
						zl=zr+(zr=zl)*0;
						x1=x2+(x2=x1)*0;
						y1=y2+(y2=y1)*0;
						tu1=tu2+(tu2=tu1)*0;
						tv1=tv2+(tv2=tv1)*0;
						tz1=tz2+(tz2=tz1)*0;
						
						irestart = ConstClass.INTERP_RHS;
			
					} 
			
				} 
				else
				if (y0 < cam.min_clip_y)
				{
					dyl = (y1 - y0);
			
					dxdyl = ((x1  - x0)  << ConstClass.FIXP16_SHIFT)/dyl;
					dudyl = ((tu1 - tu0) << ConstClass.FIXP16_SHIFT)/dyl;  
					dvdyl = ((tv1 - tv0) << ConstClass.FIXP16_SHIFT)/dyl;    
					dzdyl = ((tz1 - tz0) << ConstClass.FIXP16_SHIFT)/dyl;  
			
					dyr = (y2 - y0);	
			
					dxdyr = ((x2  - x0)  << ConstClass.FIXP16_SHIFT)/dyr;
					dudyr = ((tu2 - tu0) << ConstClass.FIXP16_SHIFT)/dyr;  
					dvdyr = ((tv2 - tv0) << ConstClass.FIXP16_SHIFT)/dyr;   
					dzdyr = ((tz2 - tz0) << ConstClass.FIXP16_SHIFT)/dyr;   
					
					dy = (cam.min_clip_y - y0);
			
					xl = dxdyl*dy + (x0  << ConstClass.FIXP16_SHIFT);
					ul = dudyl*dy + (tu0 << ConstClass.FIXP16_SHIFT);
					vl = dvdyl*dy + (tv0 << ConstClass.FIXP16_SHIFT);
					zl = dzdyl*dy + (tz0 << ConstClass.FIXP16_SHIFT);
			
					xr = dxdyr*dy + (x0  << ConstClass.FIXP16_SHIFT);
					ur = dudyr*dy + (tu0 << ConstClass.FIXP16_SHIFT);
					vr = dvdyr*dy + (tv0 << ConstClass.FIXP16_SHIFT);
					zr = dzdyr*dy + (tz0 << ConstClass.FIXP16_SHIFT);
			
					ystart = cam.min_clip_y;
			
					if (dxdyr < dxdyl)
					{
						dxdyl=dxdyr+(dxdyr=dxdyl)*0;
						dudyl=dudyr+(dudyr=dudyl)*0;	
						dvdyl=dvdyr+(dvdyr=dvdyl)*0;
						dzdyl=dzdyr+(dzdyr=dzdyl)*0;
						xl=xr+(xr=xl)*0;
						ul=ur+(ur=ul)*0;
						vl=vr+(vr=vl)*0;
						zl=zr+(zr=zl)*0;
						x1=x2+(x2=x1)*0;
						y1=y2+(y2=y1)*0;
						tu1=tu2+(tu2=tu1)*0;
						tv1=tv2+(tv2=tv1)*0;
						tz1=tz2+(tz2=tz1)*0;
						
						irestart = ConstClass.INTERP_RHS;
			
					} 
			
				} 
				else
				{
					
					dyl = (y1 - y0);
			
					dxdyl = ((x1  - x0)  << ConstClass.FIXP16_SHIFT)/dyl;
					dudyl = ((tu1 - tu0) << ConstClass.FIXP16_SHIFT)/dyl;  
					dvdyl = ((tv1 - tv0) << ConstClass.FIXP16_SHIFT)/dyl;    
					dzdyl = ((tz1 - tz0) << ConstClass.FIXP16_SHIFT)/dyl;   
					dyr = (y2 - y0);	
			
					dxdyr = ((x2 - x0)   << ConstClass.FIXP16_SHIFT)/dyr;
					dudyr = ((tu2 - tu0) << ConstClass.FIXP16_SHIFT)/dyr;  
					dvdyr = ((tv2 - tv0) << ConstClass.FIXP16_SHIFT)/dyr;   		
					dzdyr = ((tz2 - tz0) << ConstClass.FIXP16_SHIFT)/dyr;  
			
					xl = (x0 << ConstClass.FIXP16_SHIFT);
					xr = (x0 << ConstClass.FIXP16_SHIFT);
			
					ul = (tu0 << ConstClass.FIXP16_SHIFT);
					vl = (tv0 << ConstClass.FIXP16_SHIFT);
					zl = (tz0 << ConstClass.FIXP16_SHIFT);
			
					ur = (tu0 << ConstClass.FIXP16_SHIFT);
					vr = (tv0 << ConstClass.FIXP16_SHIFT);
					zr = (tz0 << ConstClass.FIXP16_SHIFT);
			
					ystart = y0;
					if (dxdyr < dxdyl)
						{
						dxdyl=dxdyr+(dxdyr=dxdyl)*0;
						dudyl=dudyr+(dudyr=dudyl)*0;	
						dvdyl=dvdyr+(dvdyr=dvdyl)*0;
						dzdyl=dzdyr+(dzdyr=dzdyl)*0;
						xl=xr+(xr=xl)*0;
						ul=ur+(ur=ul)*0;
						vl=vr+(vr=vl)*0;
						zl=zr+(zr=zl)*0;
						x1=x2+(x2=x1)*0;
						y1=y2+(y2=y1)*0;
						tu1=tu2+(tu2=tu1)*0;
						tv1=tv2+(tv2=tv1)*0;
						tz1=tz2+(tz2=tz1)*0;
						
						irestart = ConstClass.INTERP_RHS;
			
					} 
			
				} 
			
				if ((x0 < cam.min_clip_x) || (x0 > cam.max_clip_x) ||
					(x1 < cam.min_clip_x) || (x1 > cam.max_clip_x) ||
					(x2 < cam.min_clip_x) || (x2 > cam.max_clip_x))
				{
			   
			
					for (yi = ystart; yi<=yend; yi++)
					{
						xstart = ((xl + ConstClass.FIXP16_ROUND_UP) >> ConstClass.FIXP16_SHIFT);
						xend   = ((xr + ConstClass.FIXP16_ROUND_UP) >> ConstClass.FIXP16_SHIFT);
						
						ui = ul + ConstClass.FIXP16_ROUND_UP;
						vi = vl + ConstClass.FIXP16_ROUND_UP;
						zi = zl + ConstClass.FIXP16_ROUND_UP;
					
						if ((dx = (xend - xstart))>0)
						{
							du = (ur - ul)/dx;
							dv = (vr - vl)/dx;
							dz = (zr - zl)/dx;
						} 
						else
						{
							du = (ur - ul);
							dv = (vr - vl);
							dz = (zr - zl);
						} 
				
						if (xstart < cam.min_clip_x)
						{
							dx = cam.min_clip_x - xstart;
				
							ui+=dx*du;
							vi+=dx*dv;
							zi+=dx*dz;
							
							xstart = cam.min_clip_x;
				
							} 
						
						if (xend > cam.max_clip_x)
							xend = cam.max_clip_x;
				
						for (xi=xstart; xi<=xend; xi++)
						{
				            if (zi < z_ptr[yi][xi]||z_ptr[yi][xi]==null)
				            {
				               bmd.setPixel32(xi,yi,textmap.getPixel32((ui >> ConstClass.FIXP16_SHIFT) , ((vi >> ConstClass.FIXP16_SHIFT) )));
				               z_ptr[yi][xi] = zi;           
				            } 
							
							ui+=du;
							vi+=dv;
							zi+=dz;
						} 
				
						xl+=dxdyl;
						ul+=dudyl;
						vl+=dvdyl;
						zl+=dzdyl;
					
						xr+=dxdyr;
						ur+=dudyr;
						vr+=dvdyr;
						zr+=dzdyr;
						
						if (yi==yrestart)
						{
				
							if (irestart == ConstClass.INTERP_LHS)
							{
								dyl = (y2 - y1);	
					
								dxdyl = ((x2 - x1)   << ConstClass.FIXP16_SHIFT)/dyl;
								dudyl = ((tu2 - tu1) << ConstClass.FIXP16_SHIFT)/dyl;  
								dvdyl = ((tv2 - tv1) << ConstClass.FIXP16_SHIFT)/dyl;   		
								dzdyl = ((tz2 - tz1) << ConstClass.FIXP16_SHIFT)/dyl;   
					
								xl = (x1  << ConstClass.FIXP16_SHIFT);
								ul = (tu1 << ConstClass.FIXP16_SHIFT);
								vl = (tv1 << ConstClass.FIXP16_SHIFT);
								zl = (tz1 << ConstClass.FIXP16_SHIFT);
					
								xl+=dxdyl;
								ul+=dudyl;
								vl+=dvdyl;
								zl+=dzdyl;
							} 
							else
							{
								dyr = (y1 - y2);	
					
								dxdyr = ((x1 - x2)   << ConstClass.FIXP16_SHIFT)/dyr;
								dudyr = ((tu1 - tu2) << ConstClass.FIXP16_SHIFT)/dyr;  
								dvdyr = ((tv1 - tv2) << ConstClass.FIXP16_SHIFT)/dyr;   		
								dzdyr = ((tz1 - tz2) << ConstClass.FIXP16_SHIFT)/dyr;  
					
								xr = (x2  << ConstClass.FIXP16_SHIFT);
								ur = (tu2 << ConstClass.FIXP16_SHIFT);
								vr = (tv2 << ConstClass.FIXP16_SHIFT);
								zr = (tz2 << ConstClass.FIXP16_SHIFT);
					
								xr+=dxdyr;
								ur+=dudyr;
								vr+=dvdyr;
								zr+=dzdyr;
						
							} 
				
						} 
				
					}
			
				} 
				else
				{
				
					for (yi = ystart; yi<=yend; yi++)
					{
						xstart = ((xl + ConstClass.FIXP16_ROUND_UP) >> ConstClass.FIXP16_SHIFT);
						xend   = ((xr + ConstClass.FIXP16_ROUND_UP) >> ConstClass.FIXP16_SHIFT);
						
						ui = ul + ConstClass.FIXP16_ROUND_UP;
						vi = vl + ConstClass.FIXP16_ROUND_UP;
						zi = zl + ConstClass.FIXP16_ROUND_UP;
						if ((dx = (xend - xstart))>0)
						{
							du = (ur - ul)/dx;
							dv = (vr - vl)/dx;
							dz = (zr - zl)/dx;
						} 
						else
						{
							du = (ur - ul);
							dv = (vr - vl);
							dz = (zr - zl);
						} 
				
						for (xi=xstart; xi<=xend; xi++)
						{
				            if (zi < z_ptr[yi][xi]||z_ptr[yi][xi]==null)
				            {
				   			    bmd.setPixel32(xi,yi,textmap.getPixel32((ui >> ConstClass.FIXP16_SHIFT) , ((vi >> ConstClass.FIXP16_SHIFT) )));
				                z_ptr[yi][xi] = zi;       
				               
				            }
							
							ui+=du;
							vi+=dv;
							zi+=dz;
						} 
				
						xl+=dxdyl;
						ul+=dudyl;
						vl+=dvdyl;
						zl+=dzdyl;
					
						xr+=dxdyr;
						ur+=dudyr;
						vr+=dvdyr;
						zr+=dzdyr;
				
						if (yi==yrestart)
						{
				
							if (irestart == ConstClass.INTERP_LHS)
							{
								dyl = (y2 - y1);	
					
								dxdyl = ((x2 - x1)   << ConstClass.FIXP16_SHIFT)/dyl;
								dudyl = ((tu2 - tu1) << ConstClass.FIXP16_SHIFT)/dyl;  
								dvdyl = ((tv2 - tv1) << ConstClass.FIXP16_SHIFT)/dyl;   		
								dzdyl = ((tz2 - tz1) << ConstClass.FIXP16_SHIFT)/dyl;   
					
								xl = (x1  << ConstClass.FIXP16_SHIFT);
								ul = (tu1 << ConstClass.FIXP16_SHIFT);
								vl = (tv1 << ConstClass.FIXP16_SHIFT);
								zl = (tz1 << ConstClass.FIXP16_SHIFT);
					
								xl+=dxdyl;
								ul+=dudyl;
								vl+=dvdyl;
								zl+=dzdyl;
							} 
							else
							{
								dyr = (y1 - y2);	
					
								dxdyr = ((x1 - x2)   << ConstClass.FIXP16_SHIFT)/dyr;
								dudyr = ((tu1 - tu2) << ConstClass.FIXP16_SHIFT)/dyr;  
								dvdyr = ((tv1 - tv2) << ConstClass.FIXP16_SHIFT)/dyr;   		
								dzdyr = ((tz1 - tz2) << ConstClass.FIXP16_SHIFT)/dyr; 
					
								xr = (x2  << ConstClass.FIXP16_SHIFT);
								ur = (tu2 << ConstClass.FIXP16_SHIFT);
								vr = (tv2 << ConstClass.FIXP16_SHIFT);
								zr = (tz2 << ConstClass.FIXP16_SHIFT);
					
								xr+=dxdyr;
								ur+=dudyr;
								vr+=dvdyr;
								zr+=dzdyr;
						
							} 
			
						}
			
					} 
			
			  	} 
			
			} 
		}

		public static function FCMP(a:Number,b:Number):int{
			return (Math.abs(a-b)<ConstClass.EPSILON_E3)?1:0;
		}

	
}//end of class
}
